# ext动态更改表格列项
# 前言
 因业务需要,在相同业务的表格中加多一个类型,其中对应表格某些列不一样,下面来讲讲一步步的实现思路。
# 实现
# 复制
直接复制表格改改当然比较简单,但是造成了极大的代码冗余,还要修改布局,做页面切换的逻辑。所以不考虑。
# hidden
最开始认为使用hidden属性把列隐藏就行了,后来发现在grid中,hidden是初始化的时候隐藏,用户是可以在选项中把隐藏的列显示出来的,所以这条路走不通。
# ColumnModel
查阅了EXT文档,发现grid有这个属性,可以通过它控制列。
通常我们写列时都是:
createCols : function () {
	this.columns = [
		xxx,
		xxx
	]
}
ext直接会根据this.columns去生成列。
但是还有一种写法,通过colModel
createCols : function () {
	this.colModel = new Ext.grid.ColumnModel({
		// 添加动态增删列的功能
        addColumn: function(column, colIndex){
            var config = this.config;
            this.config = [];
            if(typeof colIndex == 'number'){
                config.splice(colIndex, 0, column);
            }else{
                colIndex = config.push(column);
            }
            this.setConfig(config);
            return colIndex;
        },
        removeColumn: function(index) {
            var config = this.config;
            this.config = [];
            config.splice(index, 1);
            this.setConfig(config);
        },
        columns : [
        	xxx,
        	xxx
        ]
    })
}
根据文档的解释,colModel和columns两个属性都是必须的,猜测源码里是判断两个中存在哪个就用哪个。
通过this.config可以获取到当前列的数组,那么就可以通过修改config达到动态更改列的目的。
在切换列表类型的mgr事件中
获取grid的columnModel,其中就包含了我们写的增删列的功能函数。
删除直接传列的索引
添加传需要添加的列(跟平时写的列一样的格式)和插入位置索引。
var ColumnModel = grid.getColumnModel();
ColumnModel.removeColumn(8);
ColumnModel.addColumn({
	header : _("网络随行策略"),
	width:140,
	dataIndex : "follow_network"
}, 8);
列的全部操作结束后,通过grid的fitColumns函数,重新渲染下列,即完成了列的动态改变。
grid.getView().fitColumns();
# 优化成全局方法
上面通过columnModel实现了功能,可是扩展性不强,下面将增删的方法添加到源头去。
查看Ext.grid.GridPanel表格源代码,如下
Ext.isArray(this.columns) && (this.colModel = new Ext.grid.ColumnModel(this.columns),
        delete this.columns)
有columns时就将columns传给Ext.grid.ColumnModel
这也验证了之前的猜想。
可是增删功能是需要附在ColumnModel上的,于是通过Ext.override,给Ext.grid.GridPanel加上addColumn、removeColumn方法,然后再在执行完Ext.grid.GridPanel的initComponent后将addColumn、removeColumn添加进Ext.grid.ColumnModel中 ,这样继承自该grid的页面都拥有了增删列功能。
(function () {
    var initComponent = Ext.grid.GridPanel.prototype.initComponent;
    Ext.override(Ext.grid.GridPanel, {
        addColumn: function(column, colIndex){
            var config = this.config;
            this.config = [];
            if(typeof colIndex == 'number'){
                config.splice(colIndex, 0, column);
            }else{
                colIndex = config.push(column);
            }
            this.setConfig(config);
            return colIndex;
        },
        removeColumn: function(index) {
            var config = this.config;
            this.config = [];
            config.splice(index, 1);
            this.setConfig(config);
        },
        initComponent: function() {
            initComponent.apply(this, arguments);
            Ext.override(Ext.grid.ColumnModel, {
                addColumn: this.addColumn,
                removeColumn: this.removeColumn
            })
        }
    });
})();
之前表格的列数据也可以不用ColumnModel的形式,直接用以前的columns形式即可。
# 结语
俗话说的好:好事多磨。
不断地逼近最优解,才能实现高质量的程序。
← ext实现轮播图组件 优化复制功能 →